﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using T.FAS.Runtime.Metadata.Entity;

namespace T.FAS.Runtime.ScheduleJob.Plugin
{
    public class DependencyManager
    {
        /// <summary>
        /// 获取当前元数据依赖谁
        /// </summary>
        /// <param name="metaDataContent"></param>
        /// <returns></returns>
        public static List<MetaDataDependency> GetMetaDataDependencys(IMetaDataContent metaDataContent)
        {
            var list = new List<MetaDataDependency>();
            var sJob = metaDataContent as Runtime.Metadata.Entity.ScheduleJob.ScheduleJob;
            if (sJob == null)
                return list;
            //ScheduleJob类型，如果是Action需要依赖Action
            if (sJob.JobType == Runtime.Metadata.Entity.ScheduleJob.JobType.Action)
            {
                if (!string.IsNullOrEmpty(sJob.RelatedMetaDataID))
                {
                    list.Add(new MetaDataDependency()
                    {
                        MetadataID = sJob.ID,
                        ParentMetadataID = sJob.RelatedMetaDataID,
                        DependencyType = MetaDataDependencyType.Strong
                    });
                }
            }
            return list;
        }
        /// <summary>
        /// 当前元数据变更需要通知出去的变更信息(MetaUpdateType定义的枚举项,需要在这里处理)
        /// </summary>
        /// <param name="oldMetaData"></param>
        /// <param name="newMetaData"></param>
        /// <returns></returns>
        public static MetaDataUpdateSet GetMetaDataUpdateSet(IMetaDataContent oldMetaData, IMetaDataContent newMetaData)
        {
            return null;
        }
        /// <summary>
        /// 其他元数据变更通知到当前元数据,当前元数据对变更的响应逻辑
        /// </summary>
        /// <param name="metaDataContent"></param>
        /// <param name="updateSet"></param>
        /// <returns></returns>
        public static MetaUpdateResult UpdateDependencyMetaData(IMetaDataContent metaDataContent, MetaDataUpdateSet updateSet)
        {
            var sJob = metaDataContent as Runtime.Metadata.Entity.ScheduleJob.ScheduleJob;
            if (sJob == null)
                return null;
            if (updateSet == null || updateSet.UpdateItemList == null || updateSet.UpdateItemList.Count <= 0)
                return null;

            MetaUpdateResult result = new MetaUpdateResult();
            int failCount = 0;
            int successCount = 0;

            //参数依赖处理
            foreach (var item in updateSet.UpdateItemList)
            {
                if (item.OperateType == DependencyChangeType.Update)
                {
                    if (item.UpdateType == MetaUpdateType.Item_Action_Name)
                    {
                        sJob.RelatedMetaDataCode = Convert.ToString(item.NewValue);
                        item.UpdateResult = true;
                        successCount++;
                    }
                    if (item.UpdateType == MetaUpdateType.Item_Action_InParam)
                    {
                        List<ActionMetaDataMethodParam> newAction_InParamList = JsonConvert.DeserializeObject<List<ActionMetaDataMethodParam>>(JsonConvert.SerializeObject(item.NewValue));
                        if (newAction_InParamList != null)
                        {
                            try
                            {
                                sJob.ScheduleJobDatas = new List<Runtime.Metadata.Entity.ScheduleJob.ScheduleJobData>();
                                newAction_InParamList.OrderBy(x => x.SortOrder).ToList().ForEach(x =>
                                  {
                                      sJob.ScheduleJobDatas.Add(new Runtime.Metadata.Entity.ScheduleJob.ScheduleJobData()
                                      {
                                          ID = Guid.NewGuid().ToString(),
                                          Code = x.Code,
                                          Name = x.Name,
                                          Description = x.Description,
                                          ScheduleJobID = sJob.ID,
                                          SortOrder = x.SortOrder,
                                          ParamType = Runtime.Metadata.Entity.ScheduleJob.ParamType.InParam,
                                          ParamSourceType = ParamSourceTypeConvert(x.ParamSourceType),
                                          ParamSourceID = x.SourceID,
                                          ParamSourceName = x.SourceName,
                                          IsSysDefault = x.IsSysDefault,
                                          IsNullable = false,
                                          IsList = false,
                                          Ext1 = x.Ext1,
                                          Ext2 = x.Ext2,
                                          Ext3 = x.Ext3,
                                          Creator = x.Creator,
                                          CreateTime = x.CreateTime,
                                          LastModifier = x.LastModifier,
                                          LastModifyTime = x.LastModifyTime
                                      });
                                  });
                                item.UpdateResult = true;
                                successCount++;
                            }
                            catch (Exception ex)
                            {
                                item.UpdateResult = false;
                                item.FailMessage = $"计划任务{sJob.Name}关联的Action入参内容发生变化，但系统无法自动修复，异常原因：{ex.Message}，请重新选择Action";
                                failCount++;
                            }
                        }
                        else
                        {
                            item.UpdateResult = false;
                            item.FailMessage =$"计划任务{sJob.Name}关联的Action入参内容发生变化，但变更通知中参数结构异常，系统无法自动修复，请重新选择Action";
                            failCount++;
                        }
                    }
                }
            }

            if (failCount == 0 && successCount == 0)
            {
                result.UpdateState = UpdateState.SuccessWithNoUpdate;
            }
            else if (failCount == 0 && successCount > 0)
            {
                result.UpdateState = UpdateState.Success;
                sJob.MetaDataCode = sJob.Code;
                sJob.MetaDataName = sJob.Name;
            }
            else if (failCount > 0 && successCount == 0)
            {
                result.UpdateState = UpdateState.Fail;
            }
            else if (failCount > 0 && successCount > 0)
            {
                result.UpdateState = UpdateState.PartSuccess;
                sJob.MetaDataCode = sJob.Code;
                sJob.MetaDataName = sJob.Name;
            }
            return result;
        }
        private static Runtime.Metadata.Entity.ScheduleJob.ParamSourceType ParamSourceTypeConvert(ParamSourceType actionParamSourceType)
        {
            switch (actionParamSourceType)
            {
                case ParamSourceType.CDO:
                    return Runtime.Metadata.Entity.ScheduleJob.ParamSourceType.CDO;
                case ParamSourceType.DO:
                    return Runtime.Metadata.Entity.ScheduleJob.ParamSourceType.DO;
                case ParamSourceType.DQ:
                    return Runtime.Metadata.Entity.ScheduleJob.ParamSourceType.DQ;
                case ParamSourceType.EO:
                    return Runtime.Metadata.Entity.ScheduleJob.ParamSourceType.EO;
                case ParamSourceType.SDO:
                    return Runtime.Metadata.Entity.ScheduleJob.ParamSourceType.SDO;
                case ParamSourceType.Basic:
                case ParamSourceType.UserDefine:
                default:
                    return Runtime.Metadata.Entity.ScheduleJob.ParamSourceType.Common;
            }
        }
    }
}
